﻿namespace Jsl.FxCop
{
    using Microsoft.VisualStudio.CodeAnalysis.Extensibility;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class TestBackingFieldShouldHaveSameNameAsProperty
    {
        private string instance_DifferentNameX;
        public string Instance_DifferentName
        {
            get { return this.instance_DifferentNameX; }
            set { this.instance_DifferentNameX = value; }
        }

        [TestMethod]
        public void Properties_with_non_matching_field_names_produce_problem()
        {
            new BackingFieldShouldHaveSameNameAsProperty()
                .RunRule(() => this.Instance_DifferentName)
                .HasProblem(
                    75,
                    FixCategories.NonBreaking,
                    MessageLevel.Warning,
                    "The property is named 'Instance_DifferentName' and the probable backing field is named 'instance_DifferentNameX'. Choose which name better describes the value and use it for the property and the backing field.")
                .HasNoMoreProblems();
        }

        private string _instance_Name1;
        private string _instance_Name2;
        public string Instance_MultipleNames
        {
            get { return this._instance_Name1 + this._instance_Name2; }
            set { this._instance_Name1 = value; this._instance_Name2 = value; }
        }

        [TestMethod]
        public void Properties_with_multiple_possible_fields_produce_warning()
        {
            new BackingFieldShouldHaveSameNameAsProperty()
                .RunRule(() => this.Instance_MultipleNames)
                .HasProblem(
                    75,
                    FixCategories.NonBreaking,
                    MessageLevel.Warning,
                    "The property is named 'Instance_MultipleNames' and has many potential backing fields. Choose which name better describes the value and use it for the property and the backing field.")
                .HasNoMoreProblems();
        }

        private string instance_SameName;
        public string Instance_SameName
        {
            get { return this.instance_SameName; }
            set { this.instance_SameName = value; }
        }

        [TestMethod]
        public void Properties_with_the_same_field_name_dont_produce_problems()
        {
            new BackingFieldShouldHaveSameNameAsProperty()
                .RunRule(() => this.Instance_SameName)
                .HasNoMoreProblems();
        }

        private string m_instance_SameNameWithMUnderscore;
        public string Instance_SameNameWithMUnderscore
        {
            get { return this.m_instance_SameNameWithMUnderscore; }
            set { this.m_instance_SameNameWithMUnderscore = value; }
        }

        [TestMethod]
        public void Properties_with_munderscore_field_name_dont_produce_problems()
        {
            new BackingFieldShouldHaveSameNameAsProperty()
                .RunRule(() => this.Instance_SameNameWithMUnderscore)
                .HasNoMoreProblems();
        }

        private string _instance_SameNameWithUnderscore;
        public string Instance_SameNameWithUnderscore
        {
            get { return this._instance_SameNameWithUnderscore; }
            set { this._instance_SameNameWithUnderscore = value; }
        }

        [TestMethod]
        public void Properties_with_underscore_field_name_dont_produce_problems()
        {
            new BackingFieldShouldHaveSameNameAsProperty()
                .RunRule(() => this.Instance_SameNameWithUnderscore)
                .HasNoMoreProblems();
        }

        [TestMethod]
        public void Ignore_generated_code()
        {
            new BackingFieldShouldHaveSameNameAsProperty()
                .RunPropertyRule(typeof(Targets.GeneratedCodeClass), "WrongName")
                .HasNoMoreProblems();
        }
    }
}
